package gui;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseEvent;

import particle_simulator_chem.World;

public class SearchableBoidSelect extends Dialog {

	private static World world;
	private static String[] elementNames;
	
	protected Object result;
	protected Shell shlBoidSelect;
	private Text text;
	private String title;
	private int x;
	private int y;
	private boolean center;
	private Text txtComposite;

	/**
	 * Create the dialog.
	 * @param parent
	 * @param style
	 * @wbp.parser.constructor
	 */
	
	public SearchableBoidSelect(Shell parent, int style, World world, String title, int x, int y) {
		super(parent, style);
		SearchableBoidSelect.world = world;
		SearchableBoidSelect.elementNames = world.getElements().getElementDescriptions();
		this.title = title;
		this.x = x;
		this.y = y;
	}
	
	public SearchableBoidSelect(Shell parent, int style, World world) {
		super(parent, style);
		setText("SWT Dialog");
		SearchableBoidSelect.world = world;
		SearchableBoidSelect.elementNames = world.getElements().getElementDescriptions();
		this.center = true;
	}

	/**
	 * Open the dialog.
	 * @return the result
	 */
	public Object open() {
		createContents();
		shlBoidSelect.open();
		if(this.center)
			GUIAux.centerWindow(shlBoidSelect);
		Display display = getParent().getDisplay();
		while (!shlBoidSelect.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return result;
	}

	/**
	 * Create contents of the dialog.
	 */
	private void createContents() {
		shlBoidSelect = new Shell(getParent(), getStyle());
		shlBoidSelect.setImage(SWTResourceManager.getImage(SearchableBoidSelect.class, "/particle_simulator_chem/BinaryBirdIconV.1.4.png"));
		shlBoidSelect.setSize(450, 308);
		shlBoidSelect.setText(this.title);
		shlBoidSelect.setLocation(this.x, this.y);
		
		Composite elementComposite = new Composite(shlBoidSelect, SWT.BORDER);
		elementComposite.setBounds(10, 10, 207, 258);
		
		Label label = new Label(elementComposite, SWT.CENTER);
		label.setText("Elements\r\n");
		label.setBounds(0, 0, 206, 16);
		
		final List elementList = new List(elementComposite, SWT.BORDER | SWT.V_SCROLL);
		elementList.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String[] selection = elementList.getSelection(); //must be an array of strings because compoundss can have multiple selected values
				world.setCurrentFormula(parseDescription(selection[0])); //since we only need one selected value, we can use selection[0]
				world.setCurrentTool(0); //sets the current tool to to the population controller
				//System.out.println(selection[0].substring(start_index + 1, end_index));
			}
		});
		elementList.setItems(elementNames);
		elementList.setBounds(0, 46, 206, 208);
		
		text = new Text(elementComposite, SWT.BORDER);
		text.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				elementList.setItems(getMatches(elementNames, text.getText()));
				/*
				int[] indexes = findLocation(element_names, text.getText());
				if(index != -1){
					world.setCurrentFormula(parseDescription(element_names[index]));
					world.setCurrentTool(0);
					text.setText(element_names[index]);
				}
				*/
			}
		});
		text.setBounds(0, 19, 161, 21);
		
		Button btnClear = new Button(elementComposite, SWT.NONE);
		btnClear.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				text.setText("");
			}
		});
		btnClear.setBounds(164, 19, 39, 21);
		btnClear.setText("Clear");
		
		Composite compoundComposite= new Composite(shlBoidSelect, SWT.BORDER);
		compoundComposite.setBounds(227, 10, 207, 258);
		
		Label lblCompounds = new Label(compoundComposite, SWT.CENTER);
		lblCompounds.setText("Compounds");
		lblCompounds.setBounds(0, 0, 206, 16);
		
		final List compounds = new List(compoundComposite, SWT.BORDER | SWT.V_SCROLL);
		compounds.setItems(getWorldCompounds());
		compounds.setBounds(0, 46, 206, 208);
		compounds.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String[] selection = compounds.getSelection(); //must be an array of strings because compounds can have multiple selected values
				world.setCurrentFormula(selection[0]); //since we only need one selected value, we can use selection[0]
				world.setCurrentTool(0); //sets the current tool to to the population controller
			}
		});
		
		txtComposite = new Text(compoundComposite, SWT.BORDER);
		txtComposite.setBounds(0, 19, 161, 21);
		txtComposite.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				compounds.setItems(getMatches(compounds.getItems(), txtComposite.getText()));
			}
		});
		
		Button btnCompositeClear = new Button(compoundComposite, SWT.NONE);
		btnCompositeClear.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				txtComposite.setText("");
				compounds.setItems(getMatches(compounds.getItems(), txtComposite.getText()));
			}
		});
		btnCompositeClear.setText("Clear");
		btnCompositeClear.setBounds(164, 19, 39, 21);
		
		shlBoidSelect.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				compounds.setItems(new String[]{"h", "i"});
				compounds.setItems(getWorldCompounds());
			}
			public void focusLost(FocusEvent e) {
				compounds.setItems(new String[]{"h", "i"});
				compounds.setItems(getWorldCompounds());
			}
		});
		shlBoidSelect.addMouseMoveListener(new MouseMoveListener() {
			public void mouseMove(MouseEvent arg0) {
				compounds.setItems(getWorldCompounds());
			}
		});
		
	}
	
	public static String[] getWorldCompounds(){
		String[] worldCompounds = new String[world.getCompounds().size()];
		for(int i = 0; i < worldCompounds.length; i++){
			worldCompounds[i] = world.getCompounds().get(i).toString();
		}
		return worldCompounds;
	}
	
	public String parseDescription(String description){
		int start_index = description.indexOf(" " , description.indexOf(" ") + 1); //finds the second index of a space in a string, which in this case is the space before the formula
		int end_index = description.trim().lastIndexOf(" "); //finds the last index of a space that is followed by a string, which in this case is the space after the formula
									//just in case some spaces were left at the end of the word
		return description.substring(start_index, end_index);
	}
	
	public int[] findLocation(String[] strings, String raw_target){
		int[] locations = new int[strings.length];
		String target = raw_target.toLowerCase();
		int index = 0;
		int results = 0;
		for(String string : strings){ 
			if(string.toLowerCase().contains(target)){
				locations[results] = index;
				results++;
			}
			index++;
		}
		//locations.trim();
		return locations;
	}
	
	public String[] getMatches(String[] strings, String raw_target){
		String[] raw_matches = new String[strings.length];
		String target = raw_target.toLowerCase();
		int index = 0;
		int results = 0;
		for(String string : strings){ 
			if(string.toLowerCase().contains(target)){
				raw_matches[results] = strings[index];
				results++;
			}
			index++;
		}
		String[] matches = new String[results];
		for(int i = 0; i < results; i++){
			matches[i] = raw_matches[i];
		}
		//locations.trim();
		return matches;
	}

	public Shell getShell() {
		return this.shlBoidSelect;
	}
}
